﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Program15_GDI
{
    /// <summary>
    /// 验证码
    /// </summary>
    public class ValidateCode
    {
        //创建验证码
        public static string CreateVCode(int length)
        {
            int[] randMembers = new int[length];
            int[] validateNums = new int[length];
            string validateNumberStr = "";

            //生成起始序列值  unchecked表示不检测溢出，计算出一个相对大的随机数，不需要准确结果
            int seekSeek = unchecked((int)DateTime.Now.Ticks);
            Random seekRand = new Random(seekSeek);
            //根据用户输入的位数去生成随机数
            int beginSeek = seekRand.Next(0, Int32.MaxValue - length * 10000);

            int[] seeks = new int[length];
            for (int i = 0; i < length; i++)
            {
                beginSeek += 10000;
                seeks[i] = beginSeek;
            }

            //生成随机数字
            for (int i = 0; i < length; i++)
            {
                Random rnd = new Random(seeks[i]);
                int pownum = 1 * (int)Math.Pow(10, length);
                randMembers[i] = rnd.Next(pownum, Int32.MaxValue);
            }

            //抽取随机数
            for (int i = 0; i < length; i++)
            {
                string numStr = randMembers[i].ToString();
                int numLength = numStr.Length;
                Random rnd = new Random();
                int numPosition = rnd.Next(0, numLength - 1);
                validateNums[i] = Int32.Parse(numStr.Substring(numPosition, 1));
            }

            //把数组转化为最后得到的字符串
            foreach (var item in validateNums)
                validateNumberStr += item.ToString();

            return validateNumberStr;
        }

        //创建验证码的图片
        public static byte[] CreateVCodePicture(string vCode)
        {
            Bitmap image = new Bitmap((int)Math.Ceiling(vCode.Length * 22.0), 40);
            Graphics g = Graphics.FromImage(image);
            Random r = new Random();

            try
            {
                g.Clear(Color.White);

                #region 绘制验证码

                for (var i = 0; i < vCode.Length; i++)
                {
                    Color[] colors = { Color.Crimson, Color.Aqua, Color.Chartreuse, Color.DarkOrange, Color.Gray };
                    string[] fonts = { "微软雅黑", "宋体", "Arial", "仿宋", "隶书", "Calibri" };
                    FontStyle[] fontStyles = { FontStyle.Bold, FontStyle.Italic, FontStyle.Regular, FontStyle.Underline };

                    Font font = new Font(fonts[r.Next(0, 6)], 20, fontStyles[r.Next(0, 4)]);
                    Point p = new Point(i * 20, 0);
                    g.DrawString(vCode[i].ToString(), font, new SolidBrush(colors[r.Next(0, 5)]), p);
                }

                #endregion 绘制验证码

                #region 绘制干扰线

                for (int i = 0; i < 20; i++)
                {
                    Point p1 = new Point(r.Next(0, image.Width), r.Next(0, image.Height));
                    Point p2 = new Point(r.Next(0, image.Width), r.Next(0, image.Height));
                    Color[] colors = { Color.DarkCyan, Color.Yellow, Color.Pink };
                    g.DrawLine(new Pen(colors[r.Next(0, 3)]), p1, p2);
                }

                #endregion 绘制干扰线

                #region 绘制干扰点

                for (int i = 0; i < 500; i++)
                {
                    Color[] colors = { Color.DarkCyan, Color.Yellow, Color.Pink, Color.DarkOliveGreen, Color.PeachPuff };
                    Point p = new Point(r.Next(0, image.Width), r.Next(0, image.Height));
                    //在某个坐标的像素上画点
                    image.SetPixel(p.X, p.Y, colors[r.Next(0, 5)]);
                }

                #endregion 绘制干扰点

                //保存图片
                MemoryStream stream = new MemoryStream();
                image.Save(stream, ImageFormat.Jpeg);
                return stream.ToArray();
            }
            finally
            {
                g.Dispose();
                image.Dispose();
            }
        }
    }
}